home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / Splitter.C < prev    next >
C/C++ Source or Header  |  1992-04-27  |  5KB  |  218 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "Splitter.h"
  6.  
  7. #include "Class.h"
  8. #include "Scroller.h"
  9.  
  10. const int cSplitGap= 3;
  11.  
  12. //---- SplitBar ----------------------------------------------------------------
  13.  
  14. class SplitBar: public VObject {
  15.     Splitter *splitframe;
  16.     bool vertical;
  17. public:
  18.     MetaDef(SplitBar);
  19.     SplitBar(Splitter *sf, bool v, int w, int h) : VObject(Point(w, h), cIdNone)
  20.     { splitframe= sf; vertical= v; }
  21.     void DrawInner(Rectangle r, bool feedback)
  22.     { if (!feedback) GrPaintRect(r, ePatBlack); }
  23.     Command *DoLeftButtonDownCommand(Point, Token, int);
  24.     void SetOrigin(Point at);
  25. };
  26.  
  27. NewMetaImpl(SplitBar, VObject, (TP(splitframe), TB(vertical)));
  28.  
  29. Command *SplitBar::DoLeftButtonDownCommand(Point, Token, int clicks)
  30. {
  31.     if (clicks >= 2) {
  32.     splitframe->SetSplit(vertical, Point(cSplitGap));
  33.     return gNoChanges;
  34.     }
  35.     Rectangle constrainRect(splitframe->contentRect);
  36.     if (vertical) {
  37.     constrainRect.origin.x+= constrainRect.extent.x-Width();
  38.     constrainRect.extent.x= Width();
  39.     } else {
  40.     constrainRect.origin.y+= constrainRect.extent.y-Height();
  41.     constrainRect.extent.y= Height();
  42.     }
  43.     Command *cmd= new VObjectMover(this, constrainRect);
  44.     cmd->SetType(eCmdTypeNoChange);
  45.     return cmd;
  46. }
  47.  
  48. void SplitBar::SetOrigin(Point at)
  49. {
  50.     VObject::SetOrigin(at);
  51.     splitframe->SetSplit(vertical, at);
  52. }
  53.  
  54. //---- SplitScroller -----------------------------------------------------------
  55.  
  56. class SplitScroller: public Scroller {
  57. public:
  58.     MetaDef(SplitScroller);
  59.     SplitScroller(VObject *v, Point ms, int id, ScrollDir sd)
  60.                             : Scroller(v, ms, id, sd)
  61.     { }
  62.     void Control(int, int part, void *vp);
  63. };
  64.  
  65. NewMetaImpl0(SplitScroller, Scroller);
  66.  
  67. void SplitScroller::Control(int id, int part, void *vp)
  68. {
  69.     if (part == cPartViewSize)
  70.     Scroller::Control(id, part, vp);
  71.     else
  72.     VObject::Control(GetId(), part, vp);
  73. }
  74.  
  75. //---- Splitter ----------------------------------------------------------------
  76.  
  77. NewMetaImpl(Splitter, CompositeVObject, (T(split), T(ms), TP(vop)));
  78.  
  79. Splitter::Splitter(VObject *v, Point p, int id)
  80.                     : CompositeVObject(id, (Collection*)0)
  81. {
  82.     vop= v;
  83.     ms= p;
  84.     Init(v, ms);
  85.     ResetFlag(eVObjOpen);
  86. }
  87.  
  88. void Splitter::Init(VObject *v, Point p)
  89. {
  90.     split= Point(-cSplitGap);
  91.     for (int i= 0; i < 4; i++)
  92.     Add(new SplitScroller(v, p, i, ScrollDir(i)));
  93.     Add(new SplitBar(this, FALSE, cSplitGap, cScrollBarSize));
  94.     Add(new SplitBar(this, TRUE, cScrollBarSize, cSplitGap));
  95. }
  96.  
  97. void Splitter::Open(bool mode)
  98. {
  99.     VObject::Open(mode);
  100.     At(3)->Open(mode);  // right/bottom Scroller is always open
  101. }
  102.  
  103. void Splitter::SendDown(int id , int part, void *val)
  104. {
  105.     At(3)->SendDown(id, part, val); 
  106. }
  107.  
  108. void Splitter::Control(int id, int part, void *val)
  109. {
  110.     if (id >= 0 && id < 4) {
  111.     if (part != cPartScrollPos) {
  112.         VObject *v0= At(0), *v1= At(1), *v2= At(2), *v3= At(3);
  113.         Point px, py;
  114.         px= py= *(Point*)val;
  115.         if (id < 2)
  116.         py.y= px.x= 0;
  117.         else
  118.         py.x= px.y= 0;
  119.         if (id == 1 || id == 2) {
  120.         ((Scroller*)v0)->Scroller::Control(id, part, &px);
  121.         ((Scroller*)v3)->Scroller::Control(id, part, &py);
  122.         }
  123.         if (id == 0 || id == 3) {
  124.         ((Scroller*)v1)->Scroller::Control(id, part, &px);
  125.         ((Scroller*)v2)->Scroller::Control(id, part, &py);
  126.         }
  127.     }
  128.     VObject *v= At(id);
  129.     ((Scroller*)v)->Scroller::Control(id, part, val);
  130.     } else
  131.     VObject::Control(id, part, val);
  132. }
  133.  
  134. Metric Splitter::GetMinSize()
  135. {
  136.     return At(3)->GetMinSize();
  137. }
  138.  
  139. void Splitter::TestOpen(int i, int w, int h, Point &minsize)
  140. {
  141.     Point e(w,h);
  142.     register VObject *scr= At(i);
  143.     if (e >= minsize) {
  144.     if (! scr->IsOpen())
  145.         scr->Open();
  146.     scr->SetExtent(e);
  147.     } else if (scr->IsOpen())
  148.     scr->Close();
  149. }
  150.  
  151. void Splitter::SetExtent(Point e)
  152. {
  153.     Point minsize= GetMinSize().Extent();
  154.     VObject::SetExtent(e);
  155.     
  156.     TestOpen(0, split.x, split.y, minsize);
  157.     TestOpen(1, e.x-split.x-cSplitGap, split.y, minsize);
  158.     TestOpen(2, split.x, e.y-split.y-cSplitGap, minsize);
  159.     At(3)->SetExtent(Point(e.x-split.x-cSplitGap, e.y-split.y-cSplitGap));
  160. }
  161.  
  162. void Splitter::SetOrigin(Point at)
  163. {
  164.     Point p, e= GetExtent();
  165.     
  166.     VObject::SetOrigin(at);
  167.     if (At(0)->IsOpen())
  168.     At(0)->SetOrigin(at);
  169.     if (At(1)->IsOpen())
  170.     At(1)->SetOrigin(at+Point(split.x+cSplitGap, 0));
  171.     if (At(2)->IsOpen())
  172.     At(2)->SetOrigin(at+Point(0, split.y+cSplitGap));
  173.     if (At(3)->IsOpen())
  174.     At(3)->SetOrigin(at+Point(split.x+cSplitGap, split.y+cSplitGap));
  175.     p= Point(split.x<0 ? e.x-cScrollBarSize : split.x, e.y-cScrollBarSize);
  176.     At(4)->SetOrigin(at+p);
  177.     p= Point(e.x-cScrollBarSize, split.y<0 ? e.y-cScrollBarSize : split.y);
  178.     At(5)->SetOrigin(at+p);
  179. }
  180.  
  181. void Splitter::SetSplit(bool vertical, Point at)
  182. {
  183.     Point minSize= GetMinSize().Extent(), e= GetExtent();
  184.     at-= GetOrigin();
  185.     
  186.     if (vertical) {
  187.     if (at.y < minSize.y || at.y > e.y - minSize.y)
  188.         at.y= -cSplitGap;
  189.     } else {
  190.     if (at.x < minSize.x || at.x > e.x - minSize.x)
  191.         at.x= -cSplitGap;
  192.     }
  193.     
  194.     if (split[vertical] != at[vertical]) {
  195.     split[vertical]= at[vertical];
  196.     ForceRedraw();
  197.     SetExtent(contentRect.extent);
  198.     SetOrigin(contentRect.origin);
  199.     }
  200. }
  201.  
  202. OStream& Splitter::PrintOn(OStream &s)
  203. {
  204.     VObject::PrintOn(s);
  205.     return s << vop SP << ms SP;
  206. }
  207.  
  208. IStream& Splitter::ReadFrom(IStream &s)
  209. {
  210.     VObject::ReadFrom(s);
  211.     FreeAll();
  212.     s >> vop >> ms;
  213.     Init(vop, ms);
  214.     SetExtent(GetExtent());
  215.     return s;
  216. }
  217.  
  218.